package com.yungu.swift.api.wxapi;

import com.alibaba.dubbo.config.annotation.Reference;
import com.yungu.swift.api.base.Constants;
import com.yungu.swift.api.facade.PassengerFacade;
import com.yungu.swift.assets.driver.model.dto.CarModelDto;
import com.yungu.swift.assets.driver.model.vo.DriverVo;
import com.yungu.swift.assets.driver.service.CarModelService;
import com.yungu.swift.assets.passenger.model.vo.PassengerVo;
import com.yungu.swift.assets.passenger.service.PassengerService;
import com.yungu.swift.base.ResponseData;
import com.yungu.swift.constants.CommonConstant;
import com.yungu.swift.constants.OrderConstant;
import com.yungu.swift.order.model.dto.OrderDetailDto;
import com.yungu.swift.order.model.dto.OrderDto;
import com.yungu.swift.order.model.dto.OrderFareDto;
import com.yungu.swift.order.model.param.ApiOrderUuidParam;
import com.yungu.swift.order.model.param.ApiValuationParam;
import com.yungu.swift.order.model.vo.JsonOrderDetailVo;
import com.yungu.swift.order.model.vo.OrderEstimateVo;
import com.yungu.swift.order.service.OrderAssignService;
import com.yungu.swift.order.service.OrderFareService;
import com.yungu.swift.order.service.OrderRiskControlService;
import com.yungu.swift.order.service.OrderService;
import com.yungu.swift.system.sys.service.SysCityService;
import com.yungu.swift.utils.MapUtils;
import com.yungu.swift.utils.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by cuixiuyin on 2018/5/4.
 */
@Controller
@RequestMapping("/wx/Order")
@Api(value = "【微信】【订单】乘客专车订单接口")
public class WxSpecialOrderController {

    @Reference
    private PassengerService passengerService;
    @Autowired
    private PassengerFacade passengerFacade;
    @Reference
    private OrderService orderService;
    @Reference
    private OrderAssignService orderAssignService;
    @Reference
    private OrderRiskControlService orderRiskControlService;
    @Reference
    private OrderFareService orderFareService;
    @Reference
    private SysCityService sysCityService;
    @Reference
    private CarModelService carModelService;

    private ResponseData addWxOrder(String passengerUuid, String origin, String originTitle, String originCity, Double originLng, Double originLat,
                                    String dest, String destTitle, String destCity, Double destLng, Double destLat, String actualName, String actualMobile,
                                    String carModelValuationUuid, Double planTrip, Double planFare, Integer typeTime, Long departTime, HttpServletRequest request) {
        //获取用户的信息
        PassengerVo passengerVo = passengerService.selInfo(passengerUuid).getData();
        if (passengerVo == null) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "获取不到用户信息");
        }
        //判断能否下单
        String mobile = actualMobile == null ? passengerVo.getMobile() : actualMobile;
        ResponseData result = orderRiskControlService.canPasCreateOrder(passengerUuid, WxConstants.APPID, null, mobile, typeTime);
        if (!result.isSuccess()) {
            return result;
        }
        //判断预约时间的正确性
        if (departTime != null) {
            Date date = new Date();
            if (departTime <= date.getTime()) {
                return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "预约时间不能小于当前时间");
            }
        }
        //保存订单主表order
        OrderDto orderDto = new OrderDto();
        orderDto.setPassengerUuid(passengerUuid);
        //订单类型（时效性）：1 实时订单， 2 预约订单
        orderDto.setTypeTime(typeTime);
        //订单类型（行程）：1 出租车；2 专车； 3 拼车
        orderDto.setTypeTrip(CommonConstant.BUSINESS_TYPE_SPEC);
        //订单类型（个人/企业）：1 个人；2 企业
        orderDto.setTypeEnt(OrderConstant.ORDER_TYPE_ENT_PER);
        //订单类型（本人/代客）：1 本人；2 代客
        orderDto.setTypeSelf(OrderConstant.ORDER_TYPE_SELF_ME);
        //订单类型（主/子订单）：1 主订单；2 子订单
        orderDto.setTypeMain(OrderConstant.ORDER_TYPE_MAIN);
        //订单来源：1 APP移动端；2 微信公众号；3 电话叫车；4 pc网站
        orderDto.setSource(OrderConstant.ORDER_SOURCE_WX);
        orderDto.setMainStatus(OrderConstant.ORDER_MAIN_STATUS_INITIAL);
        orderDto.setSubStatus(OrderConstant.ORDER_STATUS_WAIT);
        //预支付方式（1企业支付，2个人支付）
        orderDto.setPrepayType(OrderConstant.PREPAY_TYPE_OWN);
        orderDto.setAppid(WxConstants.APPID);

        //保存订单详情表order_detail
        OrderDetailDto orderDetailDto = new OrderDetailDto();
        String name = actualName == null ? passengerVo.getNickname() : actualName;
        //预约单唯一不同的字段
        orderDetailDto.setDeparTime(departTime == null ? new Date() : new Date(departTime));
        orderDetailDto.setActualPasNam(name);
        orderDetailDto.setActualPasMob(mobile);
        orderDetailDto.setPlanTrip(planTrip);
        orderDetailDto.setPlanFare(planFare);
        orderDetailDto.setOriginAddress(origin);
        orderDetailDto.setOriginDetailAddress(originTitle);
        orderDetailDto.setOriginCity(originCity);
        orderDetailDto.setOriginLng(originLng);
        orderDetailDto.setOriginLat(originLat);
        orderDetailDto.setOriginCityUuid(sysCityService.getCityUuidByName(originCity).getData());
        orderDetailDto.setDestAddress(dest);
        orderDetailDto.setDestDetailAddress(destTitle);
        orderDetailDto.setDestCity(destCity);
        orderDetailDto.setDestLng(destLng);
        orderDetailDto.setDestLat(destLat);
        orderDetailDto.setDestCityUuid(sysCityService.getCityUuidByName(destCity).getData());
        orderDetailDto.setCreateOn(new Date());
        //保存订单价格表
        OrderFareDto orderFareDto = new OrderFareDto();
        orderFareDto.setCarModelValuationUuid(carModelValuationUuid);
        //保存订单
        ResponseData<String> saveData = orderService.saveOrderInfo(orderDto, orderDetailDto, orderFareDto);
        if (!saveData.isSuccess()) {
            return saveData;
        }
        String orderUuid = saveData.getData();
        //执行推单或派单逻辑
        orderAssignService.assignRealTime(orderUuid);
        request.getSession().setAttribute("orderUuid", orderUuid);
        request.getSession().setAttribute("originDetailAddress", origin);
        request.getSession().setAttribute("destDetailAddress", destTitle);
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        if (departTime != null) {
            request.getSession().setAttribute("departTime", departTime);
        } else {
            request.getSession().setAttribute("departTime", formatter.format(orderDetailDto.getCreateOn()));
        }
        return setOrderValueToSession(orderUuid, request);
    }

    @RequestMapping(value = "/specialOrder/addWxRealtime")
    @ResponseBody
    @ApiOperation(value = "创建专车时时订单接口", notes = "add", response = ResponseData.class)
    public ResponseData addWxRealtime(
            @ApiParam(value = "用户ID", name = "passengerUuid", required = true) @RequestParam String passengerUuid,
            @ApiParam(value = "起点的详细地址", name = "origin", required = false) @RequestParam String origin,
            @ApiParam(value = "起点地址标题", name = "originTitle", required = false) @RequestParam String originTitle,
            @ApiParam(value = "起点城市", name = "originCity", required = false) @RequestParam String originCity,
            @ApiParam(value = "起点经度", name = "originLng", required = true) @RequestParam Double originLng,
            @ApiParam(value = "起点纬度", name = "originLat", required = true) @RequestParam Double originLat,
            @ApiParam(value = "终点的详细地址", name = "dest", required = false) @RequestParam String dest,
            @ApiParam(value = "终点地址标题", name = "destTitle", required = false) @RequestParam String destTitle,
            @ApiParam(value = "终点城市", name = "destCity", required = false) @RequestParam String destCity,
            @ApiParam(value = "终点经度", name = "destLng", required = true) @RequestParam Double destLng,
            @ApiParam(value = "终点纬度", name = "destLat", required = true) @RequestParam Double destLat,
            @ApiParam(value = "实际乘车人", name = "actualName", required = false) @RequestParam String actualName,
            @ApiParam(value = "实际乘车人电话", name = "actualMobile", required = false) @RequestParam String actualMobile,
            @ApiParam(value = "车型计价", name = "carModelValuationUuid", required = true) @RequestParam String carModelValuationUuid,
            @ApiParam(value = "预估里程（公里）", name = "planTrip", required = false) @RequestParam Double planTrip,
            @ApiParam(value = "预估价格", name = "planFare", required = false) @RequestParam Double planFare,
            HttpServletRequest request) {

        passengerUuid = (String) request.getSession().getAttribute("passengerUuid");
        carModelValuationUuid = (String) request.getSession().getAttribute("carModelValuationUuid");
        planFare = (Double) request.getSession().getAttribute("totalFare");
        return addWxOrder(passengerUuid, origin, originTitle, originCity, originLng, originLat,
                dest, destTitle, destCity, destLng, destLat, actualName, actualMobile,
                carModelValuationUuid, planTrip, planFare, CommonConstant.TYPE_TIME_REAL_TIME, null, request);

    }

    @RequestMapping(value = "/specialOrder/addWxAppotime")
    @ResponseBody
    @ApiOperation(value = "微信创建专车预约订单接口", notes = "add", response = ResponseData.class)
    public ResponseData addWxAppotime(
            @ApiParam(value = "用户ID", name = "passengerUuid") @RequestParam(required = true) String passengerUuid,
            @ApiParam(value = "起点的详细地址", name = "origin") @RequestParam(required = false) String origin,
            @ApiParam(value = "起点地址标题", name = "originTitle") @RequestParam(required = false) String originTitle,
            @ApiParam(value = "起点城市", name = "originCity") @RequestParam(required = true) String originCity,
            @ApiParam(value = "起点经度", name = "originLng", required = true) @RequestParam Double originLng,
            @ApiParam(value = "起点纬度", name = "originLat", required = true) @RequestParam Double originLat,
            @ApiParam(value = "终点的详细地址", name = "dest") @RequestParam(required = false) String dest,
            @ApiParam(value = "终点地址标题", name = "destTitle") @RequestParam(required = false) String destTitle,
            @ApiParam(value = "终点城市", name = "destCity") @RequestParam(required = false) String destCity,
            @ApiParam(value = "终点经度", name = "destLng", required = true) @RequestParam Double destLng,
            @ApiParam(value = "终点纬度", name = "destLat", required = true) @RequestParam Double destLat,
            @ApiParam(value = "预约时间", name = "departTime", required = true) @RequestParam Long departTime,
            @ApiParam(value = "实际乘车人", name = "actualName") @RequestParam(required = false) String actualName,
            @ApiParam(value = "实际乘车人电话", name = "actualMobile") @RequestParam(required = false) String actualMobile,
            @ApiParam(value = "车型估价ID", name = "carModelLeavesUuid", required = true) @RequestParam String carModelLeavesUuid,
            @ApiParam(value = "预估里程(公里)", name = "planTrip") @RequestParam(required = false) Double planTrip,
            @ApiParam(value = "预估价格", name = "planFare") @RequestParam(required = false) Double planFare,
            HttpServletRequest request) {

        passengerUuid = (String) request.getSession().getAttribute("passengerUuid");
        carModelLeavesUuid = (String) request.getSession().getAttribute("carModelValuationUuid");
        planFare = (Double) request.getSession().getAttribute("totalFare");
        return addWxOrder(passengerUuid, origin, originTitle, originCity, originLng, originLat,
                dest, destTitle, destCity, destLng, destLat, actualName, actualMobile,
                carModelLeavesUuid, planTrip, planFare, CommonConstant.TYPE_TIME_APPIONT, departTime, request);
    }

    @RequestMapping(value = "/specialOrder/getCarType")
    @ResponseBody
    @ApiOperation(value = "获取车型列表接口", notes = "车型接口", response = ResponseData.class)
    public ResponseData<List<CarModelDto>> getCarType(HttpServletRequest request) {
        Map<String, Object> map = MapUtils.build();
        map.put("appid", WxConstants.APPID);
        map.put("businessType", CommonConstant.CAR_TYPE_SPE);
        return carModelService.list(map);

    }

    @RequestMapping(value = "/specialOrder/getOrderStatus")
    @ResponseBody
    @ApiOperation(value = "获取订单状态接口", notes = "获取订单状态接口", response = ResponseData.class)
    public ResponseData<Object> getOrderStatus(@ApiParam(name = "orderId", value = "订单ID", required = true) @RequestParam String orderId) {
        OrderDto orderDto = orderService.get(orderId).getData();
        if (orderDto == null) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "未获取到订单信息");
        }
        Integer subStatus = orderDto.getSubStatus();
        //根据订单状态查找相应状态值，返回给前台
        return ResponseData.buildSuccessResponse(Constants.subStatusMap.get(subStatus), null);
    }

    @RequestMapping(value = "/specialOrder/valuation")
    @ResponseBody
    @ApiOperation(value = "专车估价接口", notes = "valuation", response = ResponseData.class)
    public ResponseData<Map<String, Object>> valuation(
            @ApiParam(value = "用户ID", name = "passengerUuid", required = false) @RequestParam(required = false) String passengerUuid,
            @ApiParam(name = "planTrip", value = "预估里程(公里)", required = false) @RequestParam(required = false) Double planTrip,
            @ApiParam(name = "planTime", value = "预估时长(分钟)", required = false) @RequestParam(required = false) Integer planTime,
            @ApiParam(name = "departTime", value = "出发时间", required = false) @RequestParam(required = false) Long departTime,
            @ApiParam(name = "carModelUuid", value = "车型id", required = false) @RequestParam(required = false) String carModelUuid,
            @ApiParam(name = "adCode", value = "区域编码", required = false) @RequestParam(required = false) String adCode,
            HttpServletRequest request) {

        if (StringUtils.isEmpty(passengerUuid)) {
            passengerUuid = (String) request.getSession().getAttribute("passengerUuid");
        }
        ApiValuationParam valuationParam = new ApiValuationParam();
        valuationParam.setAppid(WxConstants.APPID);
        valuationParam.setUserUuid(passengerUuid);
        valuationParam.setPlanTrip(planTrip);
        valuationParam.setPlanTime(planTime);
        valuationParam.setAdCode(adCode);
        valuationParam.setCarModelUuid(carModelUuid);
        valuationParam.setDepartTime(new Date(departTime));
        valuationParam.setBusinessType(CommonConstant.BUSINESS_TYPE_SPEC);
        valuationParam.setTypeTrip(1);
        ResponseData<Map<String, Object>> responseData = orderFareService.commonValuation(valuationParam);
        if (responseData.isSuccess()) {
            Map<String, Object> map = responseData.getData();
            request.getSession().setAttribute("carModelValuationUuid", map.get("carModelValuationUuid"));
            request.getSession().setAttribute("totalFare", map.get("totalFare"));
            request.getSession().setAttribute("actPaid", map.get("actPaid"));
        }
        return responseData;
    }

    @RequestMapping(value = "/specialOrder/getWxRealtimeFare")
    @ResponseBody
    @ApiOperation(value = "获取订单的时时价格和时间", notes = "获取订单的时时价格和时间")
    public ResponseData<OrderEstimateVo> getWxRealtimeFare(
            @ApiParam(name = "orderUuid", value = "订单id", required = true) @RequestParam String orderUuid,
            HttpServletRequest request) throws Exception {
        String passengerUuid = (String) request.getSession().getAttribute("passengerUuid");
        ApiOrderUuidParam orderUuidParam = new ApiOrderUuidParam();
        orderUuidParam.setUserUuid(passengerUuid);
        orderUuidParam.setOrderUuid(orderUuid);
        orderUuidParam.setAppid(WxConstants.APPID);
        return orderFareService.getRealtimeFare(orderUuidParam);
    }

    private ResponseData<JsonOrderDetailVo> setOrderValueToSession(String orderUuid, HttpServletRequest request) {
        ResponseData<JsonOrderDetailVo> responseData = orderService.getOrderDetail(orderUuid, null);
        if (responseData.isSuccess()) {
            JsonOrderDetailVo jsonOrderDetailVo = responseData.getData();
            //添加一些信息进入session
            request.getSession().setAttribute("orderUuid", jsonOrderDetailVo.getUuid());
            request.getSession().setAttribute("originDetailAddress", jsonOrderDetailVo.getOriginDetailAddress());
            request.getSession().setAttribute("destDetailAddress", jsonOrderDetailVo.getDestDetailAddress());
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
            if (jsonOrderDetailVo.getDeparTime() != null) {
                request.getSession().setAttribute("departTime", formatter.format(jsonOrderDetailVo.getDeparTime()));
            } else {
                request.getSession().setAttribute("departTime", formatter.format(jsonOrderDetailVo.getCreateOn()));
            }
            DriverVo driverVo = jsonOrderDetailVo.getDriver();
            if (null != jsonOrderDetailVo.getDriver()) {
                request.getSession().setAttribute("driverBean", driverVo);
            }
            //获取预估价格
            String passengerUuid = (String) request.getSession().getAttribute("passengerUuid");
            ApiOrderUuidParam orderUuidParam = new ApiOrderUuidParam();
            orderUuidParam.setUserUuid(passengerUuid);
            orderUuidParam.setOrderUuid(orderUuid);
            orderUuidParam.setAppid(WxConstants.APPID);
            ResponseData<OrderEstimateVo> fareData = orderFareService.getRealtimeFare(orderUuidParam);
            if (fareData.isSuccess() && fareData.getData() != null) {
                OrderEstimateVo estimateVo = fareData.getData();
                request.getSession().setAttribute("totalFare", estimateVo.getTotalFare());
                request.getSession().setAttribute("lng", estimateVo.getLng());
                request.getSession().setAttribute("lat", estimateVo.getLat());
            }
        }
        return responseData;
    }
}
